#pragma once
#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\TimerDevice"
#define SYMBOLICLINK_NAME L"\\??\\TimerDevice"
#define TIMER_COUNT 3

#define ARRARY_SIZE(a) (sizeof((a))/sizeof(*(a)))

#define LOG(format, ...) \
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__) 

#define IOCTL_TIMER_START CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_TIMER_STOP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT DeviceObject;
    WCHAR DeviceName[128]; 
    WCHAR SymbolicLinkName[128];
    LONG TimeCount;
}DEVIVCE_EXTENSION, *PDEVICE_EXTENSION;

VOID
DriverUnload(
    _In_ struct _DRIVER_OBJECT* DriverObject
);

NTSTATUS
DriverDispatch(
    _In_ struct _DEVICE_OBJECT* DeviceObject,
    _Inout_ struct _IRP* Irp
);

NTSTATUS
DeviceControl(
    _In_ struct _DEVICE_OBJECT* DeviceObject,
    _Inout_ struct _IRP* Irp
);

NTSTATUS
CreateDevice(
    _In_ PDRIVER_OBJECT pDriverObject
);


VOID
OnTimer(
    _In_ struct _DEVICE_OBJECT* DeviceObject,
    _In_opt_ PVOID Context
);

NTSTATUS
DriverEntry(
    _In_ PDRIVER_OBJECT pDriverObject,
    _In_ PUNICODE_STRING pustrRegistryPath
);

NTSTATUS
DriverDispatch(
    _In_ struct _DEVICE_OBJECT* DeviceObject,
    _Inout_ struct _IRP* Irp
);


#define PAGEDCODE  code_seg("PAGE")
#define LOCKEDCODE code_seg("PAGE")
#define INITCODE code_seg("PAGE")

#pragma alloc_text(INIT, DriverEntry, CreateDevice)
#pragma alloc_text(PAGE, DriverDispatch, DeviceControl, DriverUnload)
#pragma alloc_text(NONPAGED, OnTimer)